﻿//using System;
//using System.Collections.Generic;
//using System.Diagnostics;
//using System.Linq;
//using System.Linq.Dynamic.Core;
//using System.Net.Http;
//using System.Text;
//using System.Text.Json;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.Extensions.Hosting;
//using Microsoft.Extensions.Logging;
//using Microsoft.Extensions.Options;
//using PasteLoggerBoard.redismodel;
//using PasteLoggerBoard.serilogmodels;
//using PasteLoggerBoard.usermodels;
//using RabbitMQ.Client;
//using RabbitMQ.Client.Events;

//namespace PasteLoggerBoard.handler
//{

//    /// <summary>
//    /// 
//    /// </summary>
//    public class SerilogRabbitConsumer : IHostedService
//    {
//        /// <summary>
//        /// 
//        /// </summary>
//        private readonly ILogger<SerilogRabbitConsumer> _logger;
//        private readonly RabbitConfig _config;
//        private readonly IServiceProvider _serviceProvider;
//        private readonly IHttpClientFactory _httpClientFactory;
//        private readonly IAppCache _appCache;
//        //private readonly ChannelHelper _channelHelper;

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="logger"></param>
//        /// <param name="config"></param>
//        /// <param name="serviceProvider"></param>
//        /// <param name="appCache"></param>
//        /// <param name="httpClientFactory"></param>
//        public SerilogRabbitConsumer(
//            ILogger<SerilogRabbitConsumer> logger,
//            IOptions<RabbitConfig> config,
//            IServiceProvider serviceProvider,
//            IAppCache appCache,
//            //ChannelHelper channelHelper,
//            IHttpClientFactory httpClientFactory)
//        {
//            _logger = logger;
//            _config = config.Value;
//            _serviceProvider = serviceProvider;
//            _appCache = appCache;
//            _httpClientFactory = httpClientFactory;
//            //_channelHelper = channelHelper;
//        }

//        private IConnection conn;
//        private IModel channel;

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="cancellationToken"></param>
//        /// <returns></returns>
//        public Task StartAsync(CancellationToken cancellationToken)
//        {
//            //_listdata = new List<HistoryDate>();

//            //  Start(); 先注释，看看异常等是如何触发的
//            InstanceSystem();

//            dicsettings = new Dictionary<string, AppInfo>();

//            StartRabbit();

//            return Task.CompletedTask;
//        }

//        /// <summary>
//        /// 初始化系统
//        /// </summary>
//        private void InstanceSystem()
//        {
//            using var _dbContext = _serviceProvider.GetRequiredService<PasteLoggerBoardDbContext>();
//            if (_dbContext.Database.GetPendingMigrations().Any())
//            {
//                _dbContext.Database.Migrate();
//            }

//            var find_admin = _dbContext.UserInfo.Where(x => x.Email == "admin@admin.com").Select(x => x.Id).FirstOrDefault();
//            if (find_admin == 0)
//            {
//                var _role = new RoleInfo { IsEnable = true, Level = 0, Model = "root", Name = "root", Desc = "超级权限", Role = "root" };
//                _dbContext.Add(_role);
//                var _grade = new GradeInfo { IsEnable = true, Name = "超级管理员", Desc = "最高权限角色" };
//                _dbContext.Add(_grade);
//                _dbContext.SaveChanges();

//                var _bind = new GradeRole { GradeId = _grade.Id, RoleId = _role.Id };
//                _dbContext.Add(_bind);

//                var _user = new UserInfo { Email = "admin@admin.com", PassWord = "123456".ToMd5Lower(), CreateDate = DateTime.Now, Desc = "", Grade = "root", GradeId = _grade.Id, IsEnable = true, UserHead = "", UserName = "超级管理员" };
//                _dbContext.Add(_user);
//                _dbContext.SaveChanges();

//            }

//            _dbContext.Dispose();
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        private void StartRabbit()
//        {
//            var stopwatch = new Stopwatch();
//            stopwatch.Start();
//            IConnectionFactory connFactory = new ConnectionFactory//创建连接工厂对象
//            {
//                HostName = _config.HostName,//IP地址
//                Port = _config.Port,//端口号
//                UserName = _config.UserName,//用户账号
//                Password = _config.Password,
//                VirtualHost = _config.VirtualHost,//用户密码
//                ClientProvidedName = _config.ClientName
//            };
//            conn = connFactory.CreateConnection();

//            channel = conn.CreateModel();

//            var _exchangeName = _config.Exchange;
//            var _exchangeType = _config.ExchangeType;
//            var _durable = true;
//            var _routingKey = _config.WatchKey;
//            var _queueName = _config.QueueName;

//            //声明交换机
//            channel.ExchangeDeclare(exchange: _exchangeName, type: _exchangeType, durable: _durable);
//            //消息队列名称
//            //String queueName = "loginfo";

//            //多参数的支持，比如设定一个私信等！
//            //var idic = new Dictionary<string, object>();
//            //idic.Add("arg1","arg2");
//            //channel.QueueDeclare(queue: _config.QueueName, durable: _config.Durable, exclusive: false, autoDelete: false, arguments: idic);

//            //var args = new Dictionary<string, object>();
//            //args.Add("x-message-ttl", 3600000);

//            //声明队列
//            channel.QueueDeclare(queue: _queueName, durable: _durable, exclusive: false, autoDelete: false, arguments: null);
//            //将队列与交换机进行绑定
//            channel.QueueBind(queue: _queueName, exchange: _exchangeName, routingKey: _routingKey);
//            //声明为手动确认 一次处理五条消息
//            channel.BasicQos(0, 1, false);

//            //定义消费者
//            var consumer = new EventingBasicConsumer(channel);
//            consumer.Received += Consumer_Received;
//            consumer.ConsumerCancelled += Consumer_ConsumerCancelled;
//            consumer.Registered += Consumer_Registered;
//            consumer.Shutdown += Consumer_Shutdown;

//            //consumer.Received += (object sender, BasicDeliverEventArgs e) =>
//            //{

//            //};

//            channel.ModelShutdown += Channel_ModelShutdown;
//            channel.CallbackException += Channel_CallbackException;

//            //开启监听
//            channel.BasicConsume(queue: _queueName, autoAck: false, consumer: consumer);

//            stopwatch.Stop();
//            _logger.LogWarning($"Init Rabbit Revicer Duration {stopwatch.Elapsed.TotalMilliseconds}ms ");

//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void Channel_CallbackException(object sender, CallbackExceptionEventArgs e)
//        {
//            _logger.LogWarning("Channel_CallbackException");
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void Channel_ModelShutdown(object sender, ShutdownEventArgs e)
//        {
//            _logger.LogWarning("Channel_ModelShutdown");
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void Consumer_Shutdown(object sender, ShutdownEventArgs e)
//        {
//            _logger.LogWarning("Consumer_Shutdown");
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void Consumer_Registered(object sender, ConsumerEventArgs e)
//        {
//            _logger.LogWarning("Consumer_Registered");
//        }

//        /// <summary>
//        /// 
//        /// </summary>ps
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private void Consumer_ConsumerCancelled(object sender, ConsumerEventArgs e)
//        {
//            _logger.LogWarning("Consumer_ConsumerCancelled");
//        }

//        private Dictionary<string, AppInfo> dicsettings;

//        /// <summary>
//        /// 处理队列中的日志消息
//        /// 这里貌似可以修改成批量操作，比如10条一次
//        /// </summary>
//        /// <param name="sender"></param>
//        /// <param name="e"></param>
//        private async void Consumer_Received(object sender, BasicDeliverEventArgs e)
//        {
//            using var _scope = _serviceProvider.CreateScope();
//            using var _dbContext = _scope.ServiceProvider.GetRequiredService<IPasteLoggerBoardDbContext>();
//            try
//            {
//                var msgbtye = e.Body;
//                var msg = Encoding.UTF8.GetString(msgbtye.ToArray());
//                //这里根据e.RoutingKey 执行不一样的处理逻辑
//                var model = Newtonsoft.Json.JsonConvert.DeserializeObject<LoggerModel>(msg);
//                //关于通知告警机制 通知人 日报告 错误 异常 AppNames(外表联动) 推送次数？
//                var _now = DateTime.Now;
//                var _nowtime = _now.ToUnixTimeSeconds();
//                JsonElement protery = new JsonElement();
//                var _message = "";
//                if (model.Properties != null)
//                {
//                    _message = Newtonsoft.Json.JsonConvert.SerializeObject(model.Properties);
//                }
//                PropertiesModel _properties = null;
//                if (!String.IsNullOrEmpty(_message))
//                {
//                    _properties = Newtonsoft.Json.JsonConvert.DeserializeObject<PropertiesModel>(_message);
//                    if (_properties != null) { protery = JsonDocument.Parse(_message).RootElement; }
//                }
//                else
//                {
//                    _properties = new PropertiesModel { AppName="Unknow" };
//                }
//                var logdate = DateTime.Now;
//                long logtime = 0;
//                var _appname = _properties.AppName;
//                if (!String.IsNullOrEmpty(model.Timestamp))
//                {
//                    //2023-10-13T15:31:26.5103585+08:00
//                    if (model.Timestamp.Length > 19)
//                    {
//                        DateTime.TryParse(model.Timestamp.Substring(0, 19).Replace("T", " "), out logdate);
//                    }
//                    logtime = logdate.ToUnixTimeSeconds();
//                }
//                var _needpush = false;
//                AppInfo _setting = null;
//                if (dicsettings.ContainsKey(_appname))
//                {
//                    _setting = dicsettings[_appname];
//                }
//                else
//                {
//                    var _read = _dbContext.AppInfo.Where(x => x.AppName == _appname).OrderByDescending(x=>x.Id).AsNoTracking().FirstOrDefault();
//                    if (_read != null && _read != default)
//                    {
//                        dicsettings.Add(_appname, _read);
//                        _setting = _read;
//                    }
//                    else
//                    {
//                        _read = new AppInfo();
//                        dicsettings.Add(_appname, _read);
//                        _setting = _read;
//                    }
//                }
//                #region 日志信息按照对应的分类入库
//                switch (model.Level)
//                {
//                    case "Warning":
//                        {
//                            var one = new LogWarning
//                            {
//                                AppName = _properties?.AppName,
//                                Level = model.Level,
//                                DateLog = logdate,
//                                MessageTemplate = model.MessageTemplate,
//                                Properties = protery,
//                                ClientIp = _properties?.ClientIP.AutoSubString(32),
//                                ConnectionId = _properties?.ConnectionId.AutoSubString(32),
//                                ElapsedMilliseconds = _properties.ElapsedMilliseconds,
//                                Path = _properties?.Path.AutoSubString(128),
//                                RequestId = _properties?.RequestId.AutoSubString(32),
//                                StatusCode = _properties.StatusCode,
//                                Host = _properties?.Host.AutoSubString(64),
//                                UserAgent = _properties?.UserAgent.AutoSubString(128)
//                            };
//                            var _route_bread = false;
//                            if ( model.MessageTemplate != null)
//                            {
//                                if (!String.IsNullOrEmpty(_setting.WarnFilterRoute))
//                                {
//                                    var lines = _setting.WarnFilterRoute.Split(";");
//                                    foreach (var route in lines)
//                                    {
//                                        if (model.MessageTemplate.Contains(route))
//                                        {
//                                            _route_bread = true;
//                                            break;
//                                        }
//                                    }
//                                }
//                            }
//                            if (!_route_bread)
//                            {
//                                if (_setting.WarnSaveData)
//                                {
//                                    _dbContext.Add(one);
//                                    _message = one.Path + model.MessageTemplate;
//                                    await _dbContext.SaveChangesAsync();
//                                }
//                                else
//                                {
//                                    _logger.LogWarning(msg);
//                                }
//                            }
//                        }
//                        break;
//                    case "Error":
//                    case "Exception":
//                        {
//                            _needpush = true;
//                            var one = new LogError
//                            {
//                                AppName = _properties?.AppName,
//                                Level = model.Level,
//                                DateLog = logdate,
//                                MessageTemplate = model.MessageTemplate,
//                                Properties = protery,
//                                ClientIp = _properties?.ClientIP.AutoSubString(32),
//                                ConnectionId = _properties?.ConnectionId.AutoSubString(32),
//                                ElapsedMilliseconds = _properties.ElapsedMilliseconds,
//                                Path = _properties?.Path.AutoSubString(128),
//                                RequestId = _properties?.RequestId.AutoSubString(32),
//                                StatusCode = _properties.StatusCode,
//                                Exception = model.Exception,
//                                Host = _properties?.Host.AutoSubString(64),
//                                UserAgent = _properties?.UserAgent.AutoSubString(128)
//                            };
//                            var _route_bread = false;
//                            if (model.MessageTemplate != null)
//                            {
//                                if (!String.IsNullOrEmpty(_setting.ErrorFilterRoute))
//                                {
//                                    var lines = _setting.ErrorFilterRoute.Split(";");
//                                    foreach (var route in lines)
//                                    {
//                                        if (model.MessageTemplate.Contains(route))
//                                        {
//                                            _route_bread = true;
//                                            break;
//                                        }
//                                    }
//                                }
//                            }
//                            if (!_route_bread)
//                            {
//                                if (_setting.WarnSaveData)
//                                {
//                                    _dbContext.Add(one);
//                                    _message = one.MessageTemplate + one.Path + model.Exception;
//                                    await _dbContext.SaveChangesAsync();
//                                }
//                                else
//                                {
//                                    _logger.LogError(msg);
//                                }
//                            }
//                        }
//                        break;
//                    case "Information":
//                        {
//                            var one = new LogInfo
//                            {
//                                AppName = _properties?.AppName,
//                                Level = model.Level,
//                                DateLog = logdate,
//                                MessageTemplate = model.MessageTemplate,
//                                Properties = protery,
//                                ClientIp = _properties?.ClientIP.AutoSubString(32),
//                                ConnectionId = _properties?.ConnectionId.AutoSubString(32),
//                                ElapsedMilliseconds = _properties.ElapsedMilliseconds,
//                                Path = _properties?.Path.AutoSubString(128),
//                                RequestId = _properties?.RequestId.AutoSubString(32),
//                                StatusCode = _properties.StatusCode,
//                                Host = _properties?.Host.AutoSubString(64),
//                                UserAgent = _properties?.UserAgent.AutoSubString(128)
//                            };
//                            var _route_bread = false;
//                            if (_setting.InfoSaveData && model.MessageTemplate != null)
//                            {
//                                if (!String.IsNullOrEmpty(_setting.InfoFilterRoute))
//                                {
//                                    var lines = _setting.InfoFilterRoute.Split(";");
//                                    foreach (var route in lines)
//                                    {
//                                        if (model.MessageTemplate.Contains(route))
//                                        {
//                                            _route_bread = true;
//                                            break;
//                                        }
//                                    }
//                                }
//                                if (!_route_bread)
//                                {
//                                    _dbContext.Add(one);
//                                    await _dbContext.SaveChangesAsync();
//                                }
//                            }
//                            else
//                            {
//                                _logger.LogInformation(msg);
//                            }
//                        }
//                        break;
//                    case "appdto":
//                        {
//                            //return; 这里有问题，集群部署的时候，通知不到位啊！！！
//                            if (!String.IsNullOrEmpty(model.MessageTemplate))
//                            {
//                                var dto = Newtonsoft.Json.JsonConvert.DeserializeObject<AppInfoDto>(model.MessageTemplate);
//                                if (dto != null && dto != default)
//                                {
//                                    if (dicsettings.ContainsKey(dto.AppName))
//                                    {
//                                        dicsettings.Remove(dto.AppName);
//                                    }
//                                }
//                            }
//                            return;
//                        }
//                    default:
//                        {
//                        }
//                        break;
//                }
//                #endregion
//                if (_properties != null)
//                {
//                    if (!String.IsNullOrEmpty(_properties.AppName))
//                    {
//                        CollectPoint(_now, _properties.AppName, model.Level.ToString(), PublicString.CollectLevel);
//                        if (_properties.StatusCode != 0)
//                        {
//                            CollectPoint(_now, _properties.AppName, _properties.StatusCode.ToString(), PublicString.CollectStatus);
//                        }
//                        if (!String.IsNullOrEmpty(_properties.ClientIP))
//                        {
//                            CollectPoint(_now, _properties.AppName, _properties.ClientIP, PublicString.CollectClientIp);
//                        }
//                        if (!String.IsNullOrEmpty(_properties.Path))
//                        {
//                            CollectPoint(_now, _properties.AppName, _properties.Path, PublicString.CollectPath);
//                        }
//                    }
//                }
//                if (_needpush && model != null)
//                {
//                    if (!String.IsNullOrEmpty(_appname))
//                    {
//                        await PushErrorMessage(_dbContext, _appname, _message);
//                    }
//                }
//            }
//            catch (Exception exl)
//            {
//                _logger.LogException(exl);
//            }
//            finally
//            {
//                channel.BasicAck(e.DeliveryTag, false);
//                _dbContext.Dispose();
//                _scope.Dispose();
//            }
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="_now"></param>
//        /// <param name="appname"></param>
//        /// <param name="obj"></param>
//        /// <param name="type"></param>
//        private void CollectPoint(DateTime _now, string appname, string obj, string type)
//        {
//            var hour = _now.ToString("HH");
//            var day = _now.ToString("yyyyMMdd");
//            _appCache.HashIncrement($"{type}{day}", $"{appname}_{hour}_{obj}");
//        }

//        /// <summary>
//        /// 把错误信息等推送到对应的消息地址中
//        /// </summary>
//        /// <param name="_dbContext"></param>
//        /// <param name="appname"></param>
//        /// <param name="_message"></param>
//        /// <returns></returns>
//        private async Task<bool> PushErrorMessage(IPasteLoggerBoardDbContext _dbContext, string appname, string _message)
//        {
//            if (!String.IsNullOrEmpty(_message))
//            {
//                if (_dbContext != null)
//                {
//                    var _query_revices = from a in _dbContext.WebHookLink
//                                         join b in _dbContext.WebHooker on a.Id equals b.Id
//                                         into c
//                                         from d in c.DefaultIfEmpty()
//                                         select new
//                                         {
//                                             appname = a.AppName,
//                                             webhook = d != null ? d : null,
//                                             isenable = a.IsEnable,
//                                             level = a.Level
//                                         };
//                    var query_revies = await _query_revices.Where(x => x.appname == appname && x.isenable && x.level == "Error").AsNoTracking().ToListAsync();
//                    if (query_revies != null && query_revies.Count > 0)
//                    {
//                        var _messagebody = $"{appname} {_message}".AutoSubString(1024);
//                        foreach (var item in query_revies)
//                        {
//                            if (item.webhook != null)
//                            {
//                                if (item.webhook.IsEnable)
//                                {
//                                    if (!String.IsNullOrEmpty(item.webhook.Url))
//                                    {
//                                        await PushNoticeMessage(item.webhook.Url, _messagebody);
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//            return true;
//        }

//        /// <summary>
//        /// 推送给用户 等待
//        /// </summary>
//        /// <param name="url"></param>
//        /// <param name="message"></param>
//        private async Task<bool> PushNoticeMessage(string url, string message)
//        {
//            try
//            {
//                var json = new { msgtype = "markdown", msg_type = "markdown", content = new { title = "PasteSerilog通知", text = $"[通知]{message}" }, markdown = new { title = "PasteSerilog通知", content = $"[通知]{message}", text = $"{message}" } };
//                var postdata = (Newtonsoft.Json.JsonConvert.SerializeObject(json));
//                using (HttpContent httpcontent = new StringContent(postdata))
//                {
//                    httpcontent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
//                    var client = _httpClientFactory.CreateClient();
//                    client.Timeout = TimeSpan.FromSeconds(4);
//                    var response = await client.PostAsync(url, httpcontent);
//                    if (response.IsSuccessStatusCode)
//                    {
//                        return true;
//                    }
//                    else
//                    {
//                        _logger.LogError(await response.Content.ReadAsStringAsync());
//                        return false;
//                    }
//                }
//            }
//            catch (Exception exl)
//            {
//                _logger.LogException(exl);
//            }
//            return false;
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="cancellationToken"></param>
//        /// <returns></returns>
//        public Task StopAsync(CancellationToken cancellationToken)
//        {
//            if (channel != null)
//            {
//                channel.Dispose();
//            }
//            if (conn != null)
//            {
//                conn.Dispose();
//            }
//            return Task.CompletedTask;
//        }
//    }
//}
